home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 3 / Gold Medal Software - Volume 3 (Gold Medal) (1994).iso / graphics / 3dvect30.arj / 3D1.ASM < prev    next >
Assembly Source File  |  1993-11-18  |  25KB  |  823 lines

  1. ;3d vector routines - fast sort method
  2. ;
  3. ; - objects cannot enter inside one another
  4. ; - maxsurfs and maxpoints can be kept low - set to largest object requirement
  5. ;
  6. ; to use:
  7. ;
  8. ;          call look_at_it         ; make camera look at selected object
  9. ;          call setsincose         ; set rotation multipliers for eye
  10. ;          call show_stars         ; plot background stars
  11. ;          call makeobjs           ; plot all objects on current screen
  12. ;          call instant_mouse      ; plot mouse on screen
  13. ;          call flip_page          ; flip video pages
  14. ;          call clear_fill         ; clear video memory (last screen)
  15. ;          call resetupd           ; reset update for borders
  16. ;          call updvectors         ; move objects around, rotate them
  17.  
  18.            .386p
  19.            jumps
  20.  
  21. code32     segment para public use32
  22.            assume cs:code32, ds:code32
  23.  
  24. ; define externals
  25.  
  26.            extrn objbase:dword     ; object lists and bitmap lists are
  27.            extrn bitbase:dword     ; external! set to 0 if none
  28.            extrn bitx:dword        ; x and y sizes for 3d conversion
  29.            extrn bity:dword
  30.  
  31.            include pmode.inc       ; protected mode externals
  32.            include xmouse.inc      ; xmode mouse externals
  33.            include xmode.inc       ; xmode externals by matt pritchard
  34.            include irq.inc
  35.            include font.inc
  36.  
  37.            include macros.inc
  38.            include equ.inc
  39.  
  40.            include vars1.inc       ; labels and such
  41.            align 16
  42.            include arctan.inc      ; inverse tan
  43.            include sin.inc         ; sin/cosin table
  44.            include shading.inc     ; arctan shading tables
  45.            include math.inc        ; rotate, cos,sin,arctan...
  46.            include xscale.inc
  47.            include poly.inc        ; common ploygon stuff
  48.  
  49.            public makeobjs
  50.            public make1obj
  51.            public flush_surfaces
  52.            public init_tables
  53.  
  54. ; given esi as object number.  rotate, translate and convert to 3d the points
  55. ; of that object.  returns edi as pointer to sides.
  56.  
  57.            align 16
  58.  
  59. loadpoints:
  60.            mov bl,userotate[esi]
  61.  
  62.            mov si,whatshape[esi*2] ; get shape, bp = z distance
  63.            mov esi,objbase[esi*4]
  64.  
  65.            sub esi,4
  66.  
  67. view_is_not_ok:
  68.            add esi,4
  69.            lodsd
  70.  
  71.            cmp eax,zad            ; check if too far to see detail anyway
  72.            jb s view_is_not_ok
  73.  
  74.            lodsd
  75.            add esi,eax
  76.  
  77.            mov ax,[esi]
  78.            mov numpoints,ax
  79.            mov ax,[esi+2]
  80.            mov numsides,ax
  81.            add esi,4+50           ; skip point and side totals, skip extra data
  82.  
  83.            mov edi,2              ; reset xp pointer
  84. middle_load_points:
  85.            or  bl,bl
  86.            jne s np13             ; use different loop if no rotation
  87. np12:
  88.            mov bx,[esi]      ; x
  89.            mov cx,[esi+2]    ; y
  90.            mov bp,[esi+4]    ; z
  91.  
  92.            push edi esi
  93.            call rotate            ; rotate
  94.            add ebp,zad
  95.  
  96.            cmp ebp,ztruncate
  97.            jge s ntrunct
  98.            neg ebp
  99.            cmp ebp,ztruncate
  100.            jge s ntrunct
  101.            mov ebp,ztruncate
  102. ntrunct:
  103.            add ebx,xad
  104.            add ecx,yad
  105.            call make3d
  106.            pop esi edi
  107.            mov xp[edi],bx
  108.            mov yp[edi],cx
  109.            mov zp[edi],bp
  110.            add di,2               ; inc xp indexer
  111.            add esi,6              ; inc input pointer
  112.            dec numpoints
  113.            jne s np12
  114.  
  115.            mov pointindex,di      ; save in case of iteration surfaces
  116.  
  117.            ret                    ; edi exits with pointer to sides
  118. np13:
  119.            mov bx,[esi]      ; x
  120.            mov cx,[esi+2]    ; y
  121.            mov bp,[esi+4]    ; z
  122.  
  123.            push edi esi
  124.  
  125.            call rotatenull        ; rotation matrix already set up! (camera)
  126.  
  127.            add ebp,zad
  128.  
  129.            cmp ebp,ztruncate
  130.            jge s ntrunct2
  131.            neg ebp
  132.            cmp ebp,ztruncate
  133.            jge s ntrunct
  134.            mov ebp,ztruncate
  135. ntrunct2:
  136.            add ebx,xad
  137.            add ecx,yad
  138.            call make3d
  139.            pop esi edi
  140.            mov xp[edi],bx
  141.            mov yp[edi],cx
  142.            mov zp[edi],bp
  143.            add di,2               ; inc xp indexer
  144.            add esi,6
  145.            dec numpoints
  146.            jne s np13
  147.  
  148.            mov pointindex,di      ; save in case of iteration surfaces
  149.  
  150.            ret
  151.  
  152.            align 16
  153.  
  154. ; handle loading of bitmap from object list
  155. ;
  156. ; eg   dw 32,8,5,50,60 ;command is 32,point 8, bitmap 5, x&y scaling of 50,60
  157.  
  158. ld_special:
  159.            lodsw                  ; get from si, first is point
  160.            shl ax,1
  161.            stosw                  ; put in sides table
  162.  
  163.            mov dx,bp              ; save indexer
  164.            movzx ebp,ax           ; get point indexers
  165.            mov ax,zp[ebp]
  166.            mov zeds[ebx],ax       ; set zed for sort.
  167.            mov bp,dx
  168.  
  169.            movsw                  ; get bitmap type
  170.            movsw                  ; get x then y scaling
  171.            movsw
  172.  
  173.            mov dx,command         ; get command (for iteration bits)
  174.            mov textures[ebx],dx
  175.  
  176.            cmp zad,64000          ; bitmaps farther than 65536 screw up
  177.            jge no_norml           ; you can't see them anyway. prevent overflow
  178.            jmp ln3
  179.  
  180.            align 16
  181. loadsides:
  182.            mov showing,0          ; reset counter/indexer
  183.  
  184.            xor ebp,ebp            ; indexer to first point
  185.            mov edi,offset sides   ; get ready for lodsw and stosw
  186.            xor ebx,ebx
  187. ld_lp:
  188.            lodsw                  ; get command word
  189.            mov command,ax
  190.            mov dx,ax              ; save for later test
  191.  
  192.            mov order[ebx],bx      ; set order to 0,2,4,6,8...
  193.  
  194.            test ax,himap          ; if bitmap, do special load, or previous
  195.            jnz ld_special         ; colour (avoids pre-fetch instruction flush)
  196.  
  197.            lodsd                  ; get texture data/type
  198.            mov texture12,eax
  199.  
  200.            lodsd                  ; get colour, high byte is other side
  201.            mov colors12,eax
  202.  
  203.            lodsw                  ; get from si, first is unconditinal
  204.            shl ax,1
  205.            stosw                  ; put in di
  206.            mov cx,ax
  207. ld_loop:
  208.            lodsw                  ; get from si
  209.            shl ax,1
  210.            stosw                  ; put in di
  211.            cmp ax,cx              ; check all after first point
  212.            je s ld_exitloop
  213.  
  214.            lodsw                  ; unrolled loop
  215.            shl ax,1
  216.            stosw
  217.            cmp ax,cx
  218.            je s ld_exitloop
  219.  
  220.            lodsw
  221.            shl ax,1
  222.            stosw
  223.            cmp ax,cx
  224.            jne s ld_loop
  225.  
  226. ld_exitloop:
  227.            push ebp
  228.            push esi
  229.            push ebx
  230.  
  231.            movzx edi,bp           ; adjust bp into appropriate indexer
  232.            mov bp,[sides+edi+2]   ; get point indexers
  233.            mov cx,[zp+ebp]        ; take average of two z values, should be
  234.            mov bp,[sides+edi+0]   ; average of all but two is ok.
  235.            add cx,[zp+ebp]
  236.            mov zeds[ebx],cx       ; but any will do.
  237.  
  238.            test dx,onscr          ; find if test is for on screen pixels
  239.            jnz test_if_on_screen
  240.            test dx,both+line+point ; check if always visible
  241.            jnz its_line
  242.  
  243. return_screen:
  244.            mov bx,[sides+edi+4]
  245.  
  246.            mov dx,[xp+ebp]        ; first point
  247.            mov ax,[yp+ebp]
  248.            mov esq,ax             ; memory
  249.  
  250.            mov bp,[sides+edi+2]
  251.            mov si,[xp+ebp]        ; second point
  252.            mov ax,[yp+ebp]
  253.            mov dsq,ax             ; memory
  254.  
  255.            mov bp,bx
  256.            mov di,[xp+ebp]        ; third point
  257.            mov bp,[yp+ebp]
  258.  
  259.            call checkfront        ; check if side is visible using p1,2,3
  260.  
  261.            pop ebx
  262.            pop esi                ; return object data pointer
  263.            pop ebp                ; return where we are in sides list
  264.  
  265.            mov dx,command
  266.            or ecx,ecx
  267.            jle s test_shading     ; cx>-1 if side visible, skip if not
  268.            test dx,double         ; test to use other colour
  269.            jz s skipit            ; miss this side...
  270.            shr texture12,16
  271.            shr colors12,16
  272.            xor w texture12,inverse ; do inverse shading xor dx,256
  273. test_shading:
  274.            test w texture12,shade+last
  275.            jnz handle_shading     ; shading bit set, do it...
  276. ln2:
  277.            test dx,check          ; find out if side is only a test side
  278.            jnz s no_show
  279.  
  280.            mov ax,w texture12     ; another side added...
  281.            mov textures[ebx],ax
  282.            mov ax,w colors12
  283.            mov surfcolors[ebx],ax
  284. ln3:
  285.            inc showing
  286.            add bx,2
  287.            add ebp,maxpolys*2     ; bump ebp to next block
  288. no_show:
  289.            test dx,iterate        ; test dx,512
  290.            jnz handle_surface_iteration
  291. skipit:
  292.            test dx,normal         ; do we skip surface normal data
  293.            jz s no_norml
  294.            add esi,6
  295. no_norml:
  296.            test dx,iterate        ; test dx,512
  297.            jnz failed_iteration   ; skip iteration data if surface failure
  298.  
  299. return_iteration:
  300.            mov edi,ebp            ; set di for next stosw
  301.            add edi,offset sides
  302.  
  303.            dec numsides           ; count for next side
  304.            jne ld_lp
  305.  
  306.            ret
  307.  
  308.            align 16
  309. its_line:
  310.            pop ebx esi ebp
  311.            test w texture12,shade+last
  312.            jz s ln2
  313.  
  314. ; handle gourad/lambert shading
  315.  
  316.            align 16
  317. handle_shading:
  318.            test w texture12,last       ; test to use last colour or bitmap call
  319.            jnz ld_do_previous
  320.  
  321.            if usesteel eq yes
  322.            test w texture12,wavey
  323.            jnz ln2
  324.            endif
  325.  
  326.            push ebx esi ebp dx
  327.  
  328.            cmp lamflag,no         ; is lambert matrix set up?
  329.            je s setitup           ; jump to less likely route
  330. return:
  331.            lodsw                  ; get surface normal
  332.            movsx ebx,ax
  333.            lodsw
  334.            movsx ecx,ax
  335.            lodsw
  336.            movsx ebp,ax
  337.  
  338.            call lrotate           ; rotate surface normal by lambert matrix
  339.  
  340.            pop dx
  341.            test w texture12,inverse ; have the sides flipped? test dx,256
  342.            jnz s invert_colour    ; jump to least likely route
  343. lp_contin:
  344.            add edi,256
  345.            shr di,1               ; result -256 to +256, turn into 0-256
  346.            mov al,b shading_tables[edi] ; now into 0-15
  347.            xor ah,ah
  348.  
  349.            pop ebp esi ebx
  350.  
  351.            add w colors12,ax      ; user can have offset color in object!
  352.  
  353.            jmp ln2
  354.  
  355.            align 16
  356. invert_colour:                    ; inversion occures with other side option,
  357.            neg edi                ; always visible option, and shading option
  358.            jmp lp_contin          ; all combined!
  359.  
  360.            align 16
  361. setitup:
  362.            push esi
  363.            mov esi,currobj        ; this is object # from make1obj
  364.            call lambert           ; set up lambert maxtrix
  365.            mov lamflag,yes
  366.            pop esi
  367.            jmp s return
  368.  
  369.            align 16
  370.  
  371. ld_do_previous:
  372.            mov ax,w colors12
  373.            mov cx,surfcolors[ebx-2]
  374.            and cx,00fh            ; drop old colour block, keep shading indexer
  375.            add cx,ax              ; add new colour block
  376.            mov w colors12,cx
  377.  
  378.            jmp ln2
  379.  
  380. ; handle option 512
  381.  
  382.            align 16
  383.  
  384. handle_surface_iteration:
  385.            test dx,normal
  386.            jz s no_norml2
  387.            add esi,6              ; skip if shading normal present
  388. no_norml2:
  389.            lodsw                  ; get number of extra points in iteration
  390.            mov numpoints,ax       ; set as counter
  391.            mov cx,ax              ; save number of extra points for later use
  392.  
  393.            shl ax,1
  394.            add ax,pointindex      ; pointindex = word indexer to last point
  395.            cmp ax,maxpoints*2     ; test for overflow in points tables
  396.            jae abort_all2
  397.  
  398.            lodsw                  ; get number of sides in iteration
  399.            add numsides,ax
  400.  
  401.            add ax,showing
  402.            cmp ax,maxsurfaces-1   ; check for overflow in "sides" tables
  403.            jae abort_all2
  404.  
  405.            add esi,25*2
  406.  
  407.            or  cx,cx              ; no new points to add? (just surfaces)
  408.            je return_iteration
  409.  
  410.            push ebx ebp dx        ; save load and store locations
  411.  
  412.            mov edi,currobj        ; add more points to xp,yp,zp list
  413.            mov bl,userotate[edi]  ; because iteration is visible
  414.  
  415.            mov di,pointindex      ; movzx edi,pointindex
  416.  
  417.            call middle_load_points
  418.            pop dx ebp ebx
  419.  
  420.            jmp return_iteration
  421.  
  422.            align 16
  423.  
  424. abort_all2:
  425.            ret                    ; out of room for surfaces, return and plot
  426.  
  427. ; perform test for option 1024 - test if polygon points on screen.
  428. ; routine also tests if polygon crosses screen - eg no point is on the screen
  429. ; but the polygon covers the screen, like the front of a very big building.
  430.  
  431.            align 16
  432.  
  433. test_if_on_screen:
  434.            xor bl,bl              ; bl = quadrant flag
  435.            push dx                ; save command
  436.  
  437.            mov esi,ebp
  438. tios:
  439.            mov cx,xp[esi]         ; cx, dx =(x,y) to test
  440.            mov dx,yp[esi]
  441.  
  442.            mov ah,32              ;  32 16  8    determine where point is,
  443.            cmp cx,xmins           ;1  x  x  x    then or bl with location
  444.            jl s ytest             ;2  x  x  x
  445.            mov ah,8               ;4  x  x  x
  446.            cmp cx,xmaxs           ;
  447.            jge s ytest
  448.            mov ah,16
  449. ytest:
  450.            mov al,1
  451.            cmp dx,ymins
  452.            jl s oritall
  453.            mov al,4
  454.            cmp dx,ymaxs
  455.            jge s oritall
  456.  
  457.            cmp ah,16
  458.            je s on_screen         ; a point is on the screen, generate side...
  459.            mov al,2
  460. oritall:
  461.            or bl,ah               ; point is not on the screen, but it may
  462.            or bl,al               ; contribute to a polygon which covers the screen.
  463.  
  464.            add edi,2              ; get next connection for another test
  465.            mov si,sides[edi]
  466.            cmp si,bp              ; test if at last connection in iteration test
  467.            jne tios
  468.  
  469.            xor al,al              ; count number of bits in y (must be >2)
  470.            ror bl,1
  471.            adc al,0
  472.            ror bl,1
  473.            adc al,0
  474.            ror bl,1
  475.            adc al,0
  476.            cmp al,1
  477.            jbe s skipit2
  478.  
  479.            xor al,al              ; now count x (must be >2)
  480.            ror bl,1
  481.            adc al,0
  482.            ror bl,1
  483.            adc al,0
  484.            ror bl,1
  485.            adc al,0
  486.            cmp al,1
  487.            jbe s skipit2
  488. on_screen:
  489.            pop dx
  490.  
  491.            test dx,both           ; side is on screen
  492.            jz return_screen       ; test if alway visible
  493.  
  494.            pop ebx esi ebp        ; always, pop and test for shading
  495.            test dx,shade
  496.            jz ln2                 ; no shading - do normal return
  497.            jmp handle_shading
  498.  
  499. skipit2:
  500.            pop dx ebx esi ebp
  501.            jmp skipit
  502.  
  503. ; handle failure of option 512
  504.  
  505.            align 16
  506.  
  507. failed_iteration:
  508.            add esi,4              ; skip # of points and # of surfaces
  509.            xor ecx,ecx
  510.            lodsw                  ; number of bytes to skip in case of failure
  511.            mov cx,ax
  512.            lodsw                  ; get number of points TOTAL in iteration
  513.            shl ax,1               ; in case iteration in iteration in iteration...
  514.            add pointindex,ax
  515.            add esi,ecx
  516.            jmp return_iteration
  517.  
  518.            align 16
  519.  
  520. ; make object esi, routine assumes object is already ON!  note: esi not si!
  521.  
  522. make1obj:
  523.            mov lamflag,no
  524.            mov currobj,esi
  525.  
  526.            shl si,2               ; si = dword
  527.  
  528.            mov ebx,xs[esi]        ; displacement
  529.            sub ebx,eyex
  530.            mov ecx,ys[esi]
  531.            sub ecx,eyey
  532.            mov ebp,zs[esi]
  533.            sub ebp,eyez
  534.  
  535.            shr ebx,8              ; account for decimal places
  536.            test ebx,00800000h
  537.            jz s pm_1
  538.            or ebx, 0ff000000h
  539. pm_1:
  540.            shr ecx,8
  541.            test ecx,00800000h
  542.            jz s pm_2
  543.            or ecx, 0ff000000h
  544. pm_2:
  545.            shr ebp,8
  546.            test ebp,00800000h
  547.            jz s pm_3
  548.            or ebp, 0ff000000h
  549. pm_3:
  550.            cmp ebx,-maxz          ; check if within visible space
  551.            jl s noa2              ; if object miles away, don't bother
  552.            cmp ebx,maxz
  553.            jg s noa2
  554.  
  555.            cmp ebp,-maxz
  556.            jl s noa2
  557.            cmp ebp,maxz
  558.            jg s noa2
  559.  
  560.            cmp ecx,-maxz
  561.            jl s noa2
  562.            cmp ecx,maxz
  563.            jng s mo_misout
  564.  
  565.            align 4
  566. noa2:
  567.            ret
  568.  
  569. mo_misout:
  570.            call zsolve            ; figure out camera displacement
  571.  
  572.            cmp esi,minz           ; check if behind camera, miminum dist.
  573.            jl s noa2
  574.  
  575. ;          cmp esi,32767          ; rare case, far plane in front of far blimp,
  576. ;          jle s pm_notseg        ; plane may appear behind blimp, but for
  577. ;          mov esi,32767          ; that split second, who cares!
  578. ;pm_notseg:
  579.  
  580.            call xsolve
  581.            mov xad,edi            ; store 3d offsets
  582.            call make3dx           ; now make object farther in 3d
  583.  
  584.            cmp edi,xmit           ; tolerance is max object size/ratio
  585.            jl s noa2
  586.            cmp edi,xmat
  587.            jge s noa2
  588.  
  589.            call ysolve            ; solve y and set correct regs
  590.            mov yad,ecx
  591.            call make3dy           ; now make object farther in 3d
  592.  
  593.            cmp ecx,ymit
  594.            jl s noa2
  595.            cmp ecx,ymat
  596.            jge s noa2
  597.  
  598.            mov zad,ebp
  599.            mov zedthis,bp         ; store z for next sort
  600.  
  601.            mov xp,bx              ; save center of gravity as point 0
  602.            mov yp,cx
  603.            mov zp,bp
  604.  
  605.            mov esi,currobj        ; pop original object number
  606.  
  607.            mov al,userotate[esi]
  608.            test al,himap+point    ; check if bitmap or point
  609.            jnz  mo_special ;* make short
  610.  
  611.            mov ebx,palxref[esi*4]
  612.            mov palxref,ebx
  613.  
  614.            test al,1+himap+point  ; test to call compound routine
  615.            jnz s mk_skipc         ; skip if anything other than full rotations
  616.            call compound          ; full rotation object, calc. matrix
  617. mk_skipc:
  618.            call loadpoints        ; load points and rotate, exit di=sides
  619.            call loadsides         ; now load sides, starting at di
  620.            call sort_list         ; sort surfaces
  621.            jmp  drawvect          ; draw surfaces and exit
  622. noa:
  623.            ret
  624.  
  625. ; if userotate = 2 then draw bitmap at location x,y,z
  626.  
  627.            align 16
  628.  
  629. mo_special:
  630.            test al,point          ; check if point
  631.            jnz mo_ispoint
  632.  
  633.            push ax bx cx          ; save actual center of bitmap and command
  634.  
  635.            mov ebx,xad            ; calc size of bitmap
  636.            mov ecx,yad
  637.  
  638.            shl si,1               ; si = word
  639.            movzx edx,vxs[esi]     ; get addition for bitmap size
  640.            sub ebx,edx
  641.            sub ecx,edx
  642.  
  643.            mov si,whatshape[esi]
  644.            shl si,2               ; si = dword
  645.            sub ebx,bitx[esi]
  646.            sub ecx,bity[esi]      ; ebx,ecx = top corner of bitmap in 3d
  647.  
  648.            mov eax,bitbase[esi]
  649.            mov bitmap,eax
  650.  
  651.            call make3d            ; ebx,ecx = top corner of bitmap in 2d
  652.  
  653.            if useborders eq yes
  654.  
  655.            cmp cx,yupdate+0
  656.            jge s up_no12
  657.            mov yupdate+0,cx
  658. up_no12:
  659.            cmp bx,xupdate+0
  660.            jge s up_no32
  661.            mov xupdate+0,bx
  662. up_no32:
  663.            endif
  664.  
  665.            pop bp ax              ; bp = y, ax = x center
  666.            sub bp,cx              ; bp = y height/2
  667.            sub ax,bx              ; ax = x width/2
  668.  
  669.            if useborders eq yes
  670.            mov dx,cx
  671.            mov di,bx
  672.            endif
  673.  
  674.            add bx,xcent
  675.            add cx,ycent
  676.            mov destx,bx
  677.            mov desty,cx
  678.  
  679.            shl bp,1
  680.            shl ax,1
  681.  
  682.            mov destheight,bp
  683.            mov destwidth,ax
  684.  
  685.            if useborders eq yes
  686.            add dx,bp
  687.            add di,ax
  688.  
  689.            cmp dx,yupdate+2
  690.            jng s up_no42
  691.            mov yupdate+2,dx
  692. up_no42:
  693.            cmp di,xupdate+2
  694.            jng s up_no22
  695.            mov xupdate+2,di
  696. up_no22:
  697.            endif
  698.  
  699.            pop ax
  700.            test al,lomap-himap   ; test to use 1/4 scale bitmap or full scale
  701.            jz xscale2
  702.            jmp xscale4
  703. noa7:
  704.            ret
  705. mo_ispoint:
  706.            cmp bx,xmins            ; draw single point/bullet
  707.            jl s noa7
  708.            cmp bx,xmaxs
  709.            jge s noa7
  710.            cmp cx,ymins
  711.            jl s noa7
  712.            cmp cx,ymaxs            ; ymaxs1 if larger pixel
  713.            jge s noa7
  714.  
  715.            mov edi, current_page   ; point to active vga page
  716.            add bx,xcent
  717.            add cx,ycent
  718.  
  719.            mov si,cx
  720.            shl si,1
  721.            mov ax,[esi+fastimultable] ; get offset to start of line
  722.  
  723.            mov cx, bx              ; copy to extract plane # from
  724.            shr bx, 2               ; x offset (bytes) = xpos/4
  725.            add bx, ax              ; offset = width*ypos + xpos/4
  726.  
  727.            mov ax, map_mask_plane1 ; map mask & plane select register
  728.            and cl, plane_bits      ; get plane bits
  729.            shl ah, cl              ; get plane select value
  730.            out_16 sc_index, ax     ; select plane
  731.  
  732.            movzx ebx,bx
  733.            mov [edi+ebx],b bulletcolour ; draw pixel, red or yellow is good
  734. ;          add edi,xactual/4
  735. ;          mov [edi+ebx],b bulletcolour2 ; draw larger bullet/pixel
  736.  
  737. ; if drawing larger pixel, change above code to this!
  738. ;          cmp cx,ymaxs1
  739. ;          jge s noa7
  740.  
  741.            ret
  742.  
  743.            align 16
  744.  
  745. set_makeorder:
  746.  
  747.            i=0
  748.            rept maxobjects        ; macro to produce unrolled loop
  749.            mov makeorder+i*2,i+1  ; set makeorder to 0,1,2,3,4
  750.            i=i+1
  751.            endm
  752.  
  753.            ret
  754.  
  755.            align 16
  756.  
  757. makeobjs:                         ; make all objects, unrolled loop
  758.            i=0
  759.  
  760.            rept maxobjects
  761.            local itsoff
  762.  
  763.            mov ax,32767           ; in case of abort
  764.            movzx esi,makeorder+i*2
  765.            test onoff[esi],255    ; check on/off
  766.            jz s itsoff
  767.  
  768.            call make1obj
  769.            mov ax,zedthis         ; get z and save for re_sort
  770. itsoff:
  771.            mov finalzed+i*2,ax
  772.  
  773.            i=i+1
  774.            endm
  775.  
  776. ; bubble sort for entire objects, fastest when already sorted (assumed)
  777.  
  778.            basedif equ makeorder-finalzed
  779.  
  780. re_sort:
  781.            mov ecx,maxobjects-1
  782.            mov edx,offset finalzed-2
  783.            xor bx,bx              ; sort flag
  784.            xor esi,esi
  785. nextccx:
  786.            add edx,2
  787.            mov esi,maxobjects*2-2+offset finalzed
  788. nextddx:
  789.            sub esi,2
  790.  
  791.            mov ax,[esi+2]
  792.            cmp ax,[esi]
  793.            jle s donotng
  794.            xchg ax,[esi]          ; don't flip entire object, just indexers
  795.            xchg ax,[esi+2]
  796.            mov ax,basedif[esi+2]
  797.            xchg ax,basedif[esi]
  798.            xchg ax,basedif[esi+2]
  799.            inc bx                 ; flag that one sorted
  800. donotng:
  801.            cmp esi,edx
  802.            jnle s nextddx
  803.  
  804.            or  bx,bx              ; re-sort until no more sorts
  805.            loopne s nextccx
  806. quickex:
  807.            ret
  808.  
  809. ; initialize ordering before beginning 3d animation
  810.  
  811. init_tables:
  812.            call set_makeorder
  813.            ret
  814.  
  815. flush_surfaces:
  816.            call sort_list     ; sort sides according to z distance
  817.            call drawvect      ; draw 'em on da screen
  818.            ret
  819.  
  820. code32     ends
  821.            end
  822.  
  823.